﻿#region License
/*

	Copyright (C) 2008 Oliver Charles, Daniel Hollander

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
	
*/
#endregion

namespace Moebius.Rendering
{
    /// <summary>
    /// Represents the planes that make up the ZBuffer.
    /// </summary>
    public struct ZBufferPlanes
    {
        #region Properties

        private float mNear;
        private float mFar;

        /// <summary>
        /// Gets the distance of the near plane from the viewport
        /// </summary>
        public float Near
        {
            get { return mNear; }
            set { mNear = value; }
        }

        /// <summary>
        /// Gets the distance of the far plane from the viewport
        /// </summary>
        public float Far
        {
            get { return mFar; }
            set { mFar = value; }
        }

        #endregion

        #region Constructors

        /// <summary>
        /// Create a new representation of ZBuffer Planes
        /// </summary>
        /// <param name="near">The distance of the near plane from the viewport.</param>
        /// <param name="far">The distance of the far plane from the viewport.</param>
        public ZBufferPlanes(float near, int far)
        {
            mNear = near;
            mFar = far;
        }

        #endregion

        #region Object overrides

        /// <summary>
        /// Checks to see if 2 <see cref="ZBufferPlanes"/> are equal
        /// </summary>
        /// <param name="obj">The <see cref="ZBufferPlanes"/> to check against</param>
        /// <returns>True if the <see cref="ZBufferPlanes"/> instances are equal, false if not.</returns>
        public override bool Equals(object obj)
        {
            if(obj == null) return false;

            if (obj.GetType() != GetType()) return false;
            ZBufferPlanes asZBufferPlanes = (ZBufferPlanes) obj;

            if (!mNear.Equals(asZBufferPlanes.mNear)) return false;
            if (!mFar.Equals(asZBufferPlanes.mFar)) return false;

            return true;
        }

        /// <summary>
        /// Gets a hashcode for this instance.
        /// </summary>
        /// <returns>A hashcode for this instance.</returns>
        public override int GetHashCode()
        {
            return ((int)mNear ^ ((int)mNear << 32)) ^ ((int)mFar ^ ((int) mFar << 32));
        }

        #endregion

        #region Operator overloads

        /// <summary>
        /// Checks to see if 2 <see cref="ZBufferPlanes"/> are equal
        /// </summary>
        /// <param name="left">The left hand side of the comparison</param>
        /// <param name="right">The right hand side of the comparsion</param>
        /// <returns>True if the <see cref="ZBufferPlanes"/> instances are equal, false if not.</returns>
        public static bool operator ==(ZBufferPlanes left, ZBufferPlanes right)
        {
            return !(left != right);
        }

        /// <summary>
        ///  Checks to see if 2 <see cref="ZBufferPlanes"/> are not equal
        /// </summary>
        /// <param name="left">The left hand side of the comparison</param>
        /// <param name="right">The right hand side of the comparsion</param>
        /// <returns>True if the <see cref="ZBufferPlanes"/> instances are not equal, false if they are equal.</returns>
        public static bool operator !=(ZBufferPlanes left, ZBufferPlanes right)
        {
            if(left.mNear != right.mNear) return true;
            if(left.mFar != right.mFar) return true;
            return false;
        }

        #endregion
    }

    /// <summary>
    /// Options to create a <see cref="RenderingDevice"/>
    /// </summary>
    public sealed class GraphicsOptions
    {
        #region Properties

        private ZBufferPlanes mZBufferPlanes;

        /// <summary>
        /// Gets or sets the ZBuffer planes.
        /// </summary>
        public ZBufferPlanes ZBufferPlanes
        {
            get { return mZBufferPlanes; }
            set { mZBufferPlanes = value; }
        }

        #endregion

        #region Constructors

        /// <summary>
        /// Create a new instance of <see cref="GraphicsOptions"/> with the default properties
        /// </summary>
        public GraphicsOptions()
        {
            mZBufferPlanes = new ZBufferPlanes(0.1f, 100);
        }

        #endregion
    }
}
